import pandas as pd #pandas 数据处理模块
import os #os 操作系统交互的核心工具
import codecs #处理文本编码与解码的核心工具
import re #正则表达式操作模块
import zhconv #中文简繁体转换的工具
import jieba #分词器
import jieba.posseg as psg #分词器子模块 能够同时返回分词结果和每个词的词性标签
from sklearn.feature_extraction.text import CountVectorizer #通过词频统计将文本数据转换为数值矩阵
import pickle #Python 标准库中用于对象序列化和反序列化

# 邮件数据清洗
def clean_data(content):
    # 1. 去除非中文字符
    content = re.sub(r'[^\u4e00-\u9fa5]','',content)
    # 2. 繁体字转简体
    content = zhconv.convert(content,'zh-cn')
    # 3. 分词，过滤词性
    content_pos = psg.cut(content) # 同时返回分词结果和每个词的词性标签
    print(content_pos)
    allow_pos = ['n', 'nr', 'ns', 'nt', 'v','a']
    words = []
    for word,pos in content_pos:
        if pos in allow_pos:
            words.append(word)
    return ' '.join(words) # 返回字符串

    # return words # 直接返回清洗后的词列表

# 真正清洗每一封邮件内容的代码
def clean_data_main():
    # 1. 加载原始数据
    data = pd.read_csv('data/01_原始训练集.csv')

    contents,labels = [],[]

    for content,label in zip(data['content'].values,data['label'].values):
        if len(clean_data(content)) != 0:
            contents.append(clean_data(content))
            labels.append(label)

    # 5. 保存成训练集
    # train_data = pd.DataFrame({'content':contents,'label':labels})
    # train_data.to_csv('data/02_清洗_训练集.csv')


# 提取特征，准备模型训练需要的数据集
def extract_email_feature():
    data = pd.read_csv('data/02_清洗_训练集.csv')
    # 词频向量转换器-- 保留10000个特征
    transfer = CountVectorizer(max_features=10000)
    content_feature = transfer.fit_transform(data['content'])

    content_feature_dict = {}
    content_feature_dict['x'] = content_feature.toarray().tolist()
    content_feature_dict['y'] = data['label'].tolist()

    # 将处理好的特征保存为二进制文件，提升读取效率
    with open('data/03_模型训练数据.pkl', 'wb') as f:
        pickle.dump(content_feature_dict, f, protocol=3) # 生成 03_模型训练数据.pkl

    # ========== 注意：我们需要保存词特征列表 ，方便后面的测试&预测时都使用相同的特征词列表
    feature_names = transfer.get_feature_names_out()
    with open('data/03_模型训练特征.pkl', 'wb') as f:
        pickle.dump(feature_names, f, protocol=3)

# clean_data_main()
extract_email_feature()
